import warnings
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt

from sklearn.preprocessing import StandardScaler,PolynomialFeatures
from sklearn.naive_bayes import GaussianNB
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.metrics import accuracy_score


warnings.filterwarnings(action='ignore', category=FutureWarning)
## 设置属性防止中文乱码
mpl.rcParams['font.sans-serif']=[u'simHei']
mpl.rcParams['axes.unicode_minus']=False

def run():
    # 花萼长度、花萼宽度，花瓣长度，花瓣宽度
    #iris_feature_E = 'sepal length', 'sepal width', 'petal length', 'petal width'
    #iris_class = 'Iris-setosa', 'Iris-versicolor', 'Iris-virginica'
    iris_feature_C = u'花萼长度', u'花萼宽度', u'花瓣长度', u'花瓣宽度'
    features=[2,3]
    ## 读取数据
    path='../data/iris.data' # 数据文件路径
    data=pd.read_csv(path,header=None)
    X=data[list(range(4))]
    X=X[features]
    Y=pd.Categorical(data[4]).codes ## 直接将数据特征转换为0，1,2
    print("总样本数目：%d；特征属性数目：%d" % X.shape)
    ## 0. 数据分割，形成模型训练数据和测试数据
    X_train,X_test,Y_train,Y_test=train_test_split(X,Y,train_size=0.8,random_state=14)
    print ("训练数据集样本数目：%d, 测试数据集样本数目：%d" % (X_train.shape[0],X_test.shape[0]))
    ## 高斯贝叶斯模型构建
    pipline=Pipeline([
        ('sc',StandardScaler()), #标准化，把它转化成了高斯分布 
        ('poly',PolynomialFeatures(degree=1)),
        ('gnb',GaussianNB())       
    ])
    ## 训练模型
    pipline.fit(X_train, Y_train)
    ## 计算预测值并计算准确率
    Y_train_predict=pipline.predict(X_train)
    print ('训练集准确度: %.2f%%' % (100*accuracy_score(Y_train,Y_train_predict)))
    Y_test_predict=pipline.predict(X_test)
    print ('测试集准确度：%.2f%%' % (100*accuracy_score(Y_test,Y_test_predict)))
    ## 产生区域图
    M,N=500,500 # 横纵各采样多少个值
    X1_min1,X2_min1=X_train.min()
    X1_max1,X2_max1=X_train.max()
    X1_min2,X2_min2=X_test.min()
    X1_max2,X2_max2=X_test.max()
    X1_min=np.min((X1_min1,X1_min2))
    X1_max=np.max((X1_max1,X1_max2))
    X2_min=np.min((X2_min1,X2_min2))
    X2_max=np.max((X2_max1,X2_max2))
    
    t1=np.linspace(X1_min,X1_max,M)
    t2=np.linspace(X2_min,X2_max,N)
    X1,X2=np.meshgrid(t1,t2) # 生成网格采样点
    X_show=np.dstack((X1.flat,X2.flat))[0] # 测试点
    cm_light=mpl.colors.ListedColormap(['#77E0A0', '#FF8080', '#A0A0FF'])
    cm_dark=mpl.colors.ListedColormap(['g', 'r', 'b'])
    Y_show_predict=pipline.predict(X_show) # 预测值
    Y_show_predict=Y_show_predict.reshape(X1.shape)
    ## 画图
    plt.figure(facecolor='w')
    plt.pcolormesh(X1,X2,Y_show_predict,cmap=cm_light) # 预测值的显示
    plt.scatter(X_train[features[0]], X_train[features[1]], c=Y_train, edgecolors='k', s=50, cmap=cm_dark)
    plt.scatter(X_test[features[0]], X_test[features[1]], c=Y_test, edgecolors='k', s=120, marker='^', cmap=cm_dark)
    plt.xlabel(iris_feature_C[features[0]],fontsize=13)
    plt.ylabel(iris_feature_C[features[1]],fontsize=13)
    plt.xlim(X1_min,X1_max)
    plt.ylim(X2_min,X2_max)
    plt.title(u'GaussianNB对鸢尾花数据的分类结果, 正确率:%.3f%%' %(100*accuracy_score(Y_test, Y_test_predict)),fontsize=18)
    plt.grid(True)
    plt.show()
    
 
run()
